package com.foreveross.proxyip.core.redis;

import java.util.HashMap;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.Protocol;
import redis.clients.jedis.Transaction;

import com.foreveross.proxyip.entity.BaseCodeEntity;
import com.foreveross.proxyip.infra.InstanceFactory;
import com.foreveross.proxyip.infra.base.ddd.repository.IBaseRepository;
import com.foreveross.proxyip.util.SerializeUtil;


/**s
 * 
 * @author lyq
 *
 */
@SuppressWarnings("rawtypes")
public class RedisManager {
	protected static final Logger log =  LoggerFactory.getLogger(RedisManager.class);
	static volatile RedisManager redisNanager = null;
	
	
	public java.util.Map<String,Map> channelMaps = new HashMap<String,Map>();

	JedisPool pool;
	String host = "172.16.1.243:6379";
	
	void destoryPool(){
		pool.destroy();
		pool = null;
		log.info("JedisPool destroy!!!!!!");
	}
	
	JedisPool getJedisPool (){
		if(pool==null){
			synchronized (channelMaps) {
				if(pool==null){
					String [] params = {"baseCode","REDIS_HOST"};
					List<BaseCodeEntity> list  = InstanceFactory.getInstance(IBaseRepository.class,"entityHibernateRepository").queryResult("from BaseCodeEntity t where t.code = ? and t.key = ?",params);
					BaseCodeEntity code = list.get(0);
					host = code.getValue();
					JedisPoolConfig config = new JedisPoolConfig();
					config.setMaxActive(500);
					config.setMaxWait(1000*10);
					config.setMaxIdle(300);
					config.setTestOnBorrow(true);
					String [] uri = StringUtils.split(host,":");
					//pool = new JedisPool(config,uri[0],Integer.parseInt(uri[1]),10000);
					pool = new JedisPool(config,uri[0],Integer.parseInt(uri[1]), 5000, uri.length == 3 ? uri[2] : null, Protocol.DEFAULT_DATABASE);
					log.info("create a JedisPool success!!!!!!");
		//			publicMap = new PoolMap("proxyIpPublic");
				}
			}
//		ipStoreMap = new IpStoreMap(pool);
		}
		
		
		return pool;
	}
	
	
	public static synchronized RedisManager getInstance(){
		if(redisNanager==null){
			redisNanager = new RedisManager();
		}
		return redisNanager;
	}
	/**
	 * 渠道池是一个队列集,遵循先进先出
	 * @param poolName
	 * @throws PiRedisExecption 
	 */
	
	public void lPush(final String name,final String value) throws PiRedisExecption{
		new RedisExecutor() {
			@Override
			public Object run() throws Exception {
				jedis.lpush(name, value);
				return null;
			}
		}.exec();
	}
	
	public void lPush(Transaction tran ,String name,String value){
//		try{
			tran.lpush(name, value);
//		}finally{
//			
//		}
	}
	
	
	public String rPop(final String poolName) throws PiRedisExecption{
		return new RedisExecutor<String>() {
			@Override
			public String run() throws Exception {
				return jedis.rpop(poolName);
			}
		}.exec();
		
	}
	
	public void lPush(final byte[] name,final byte[] value) throws PiRedisExecption{
		new RedisExecutor() {
			@Override
			public Object run() throws Exception {
				return jedis.lpush(name, value);
			}
		}.exec();
	}
	
	
	
	public Object lindex(final byte[] name,final Integer index) throws PiRedisExecption {
		return new RedisExecutor() {
			@Override
			public Object run() throws Exception {
				if(index==null){
					return null;
				}
				return SerializeUtil.unserialize( jedis.lindex(name, index.longValue()));
			}
		}.exec();
	}
	
	public byte[] rPop(final byte[] poolName) throws PiRedisExecption{
		return new RedisExecutor<byte[]>() {
			@Override
			public byte[] run() throws Exception {
				return jedis.rpop(poolName);
			}
		}.exec();
		
	}
	
	public Long len(final String name) throws PiRedisExecption{
		return new RedisExecutor<Long>() {
			@Override
			public Long run() throws Exception {
				return jedis.llen(name);
			}
		}.exec();
	}
	
	public Long len(final byte[]name) throws PiRedisExecption{
		return new RedisExecutor<Long>() {
			@Override
			public Long run() throws Exception {
				return jedis.llen(name);
			}
		}.exec();
	}
	
	
	public Long setnx(final String key,final String value,final Integer expire) throws PiRedisExecption {
//		return setnx(null, key, value, expire);
		return new RedisExecutor<Long>() {
			@Override
			public Long run() throws Exception {
				Long result = jedis.setnx(key,value);
				
				if(result == 1L){
					jedis.expire(key, expire);
				}
				
				return result;
			}
		}.exec();
	}
	
	public String get(final String key) throws PiRedisExecption {
//		return setnx(null, key, value, expire);
		return new RedisExecutor<String>() {
			@Override
			public String run() throws Exception {
				String result = jedis.get(key);
			
				return result;
			}
		}.exec();
	}
	
	public Boolean contain(final String key) throws PiRedisExecption {
//		return setnx(null, key, value, expire);
		return new RedisExecutor<Boolean>() {
			@Override
			public Boolean run() throws Exception {
				return jedis.exists(key);
//				if(result==1L){
//					jedis.expire(key, expire);
//				}
//				return result;
			}
		}.exec();
		
	}

	
	public Long del(final String key) throws PiRedisExecption{
		return new RedisExecutor<Long>() {
			@Override
			public Long run() throws Exception {
				return jedis.del(key);
			}
		}.exec();
		
	}
	public Long del(final byte[] key) throws PiRedisExecption{
		return new RedisExecutor<Long>() {
			@Override
			public Long run() throws Exception {
				return jedis.del(key);
			}
		}.exec();
		
	}
	
	public static void main(String[] args) {
		JedisPoolConfig config = new JedisPoolConfig();
		config.setMaxActive(5000);
		config.setMaxWait(1000*10);
		config.setMaxIdle(300);
		config.setTestOnBorrow(true);
		final JedisPool pool = new JedisPool(config, "172.16.1.243", 6379, Protocol.DEFAULT_TIMEOUT, "123456", Protocol.DEFAULT_DATABASE);
		//JedisPool pool = new JedisPool(config, "115.28.0.97", 6379, Protocol.DEFAULT_TIMEOUT, null, Protocol.DEFAULT_DATABASE);
		Jedis jedis = pool.getResource();
		System.out.println(jedis.info());
	}
}
